using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameManager : MonoBehaviour
{
	public delegate void GameActions();

	private static GameManager instance;

	public Transform charactersContainer;

	[SerializeField]
	private PlayerCharacter playerCharacter;

	private int playerCharacterIndex;

	public BoostButton boostButton;

	[HideInInspector]
	public Character[] characters;

	public Texture2D hueTex;

	public Color[] colors;

	public FidgetStore FidgetStore;

	private Queue<Character> deadCharacters;

	private Vector2 raySize;

	public float LastGameLenght;

	public bool screenshotTaken;

	private float startTime;

	public static GameManager Instance
	{
		get
		{
			return instance;
		}
	}

	public PlayerCharacter PlayerCharacter
	{
		get
		{
			return playerCharacter;
		}
	}

	public int SelectedItemIndex
	{
		get
		{
			return PlayerPrefs.GetInt("SelectedItemIndex", 0);
		}
		set
		{
			PlayerPrefs.SetInt("SelectedItemIndex", value);
		}
	}

	public int SelectedSkinIndex
	{
		get
		{
			return PlayerPrefs.GetInt("SelectedSkinIndex", 0);
		}
		set
		{
			PlayerPrefs.SetInt("SelectedSkinIndex", value);
		}
	}

	public static event GameActions OnGameStart;

	public static event GameActions OnGameEnd;

	private void Awake()
	{
		BGMManager.Instance.Init();
		SFXManager.Instance.Init();
		if (instance == null)
		{
			instance = this;
		}
		else
		{
			UnityEngine.Object.Destroy(base.gameObject);
		}

		Screen.sleepTimeout = -1;
		deadCharacters = new Queue<Character>();
		characters = new Character[charactersContainer.childCount];
		for (int i = 0; i < charactersContainer.childCount; i++)
		{
			characters[i] = charactersContainer.GetChild(i).GetChild(0).GetComponent<Character>();
		}
		playerCharacter.transform.position = GetRandomPosition(5f);
		GenerateMassCountByLevel(700);
		raySize = new Vector2(15f, 10f);
		LastGameLenght = 0f;
	}

	private void Start()
	{
		BGMManager.Instance.PlayBGM(Const.BGM1);
		playerCharacterIndex = playerCharacter.transform.parent.GetSiblingIndex();
		for (int i = 0; i < characters.Length; i++)
		{
			if (i != playerCharacterIndex)
			{
				InitializePlayer(characters[i], i);
			}
		}
		StartCoroutine(RevivePlayerRoutine());
	}

	public void InitializePlayer(Character character, int index, int mass = 100)
	{
		Vector2 zero = Vector2.zero;
		bool flag = false;
		if (index != playerCharacterIndex)
		{
			zero = ((!playerCharacter.IsAlive) ? GetRandomAIPosition(FollowingCamera.instance.transform.position) : GetRandomAIPosition(playerCharacter.Position));
		}
		else
		{
			zero = Values.Instance.PlayerSpawnPositions[UnityEngine.Random.Range(0, Values.Instance.PlayerSpawnPositions.Length)];
			Collider2D[] array = Physics2D.OverlapBoxAll(zero, raySize, 0f, 4352);
			if (array.Length > 0)
			{
				for (int i = 0; i < array.Length; i++)
				{
					if (array[i].CompareTag(Values.Instance.CharacterTag))
					{
						array[i].GetComponent<Character>().SetPosition(GetRandomAIPosition(zero));
					}
					else if (array[i].CompareTag(Values.Instance.BubbleTag))
					{
						array[i].GetComponent<Bubble>().Finalize();
					}
				}
			}
		}
		character.Initialize(index, zero, mass);
	}

	private Vector2 GetRandomAIPosition(Vector3 position)
	{
		if (position.x > (float)(Values.Instance.AreaSize / 2))
		{
			if (position.y > (float)(Values.Instance.AreaSize / 2))
			{
				return new Vector2(UnityEngine.Random.Range(5f, position.x - 15f), UnityEngine.Random.Range(5f, position.y - 10f));
			}
			return new Vector2(UnityEngine.Random.Range(5f, position.x - 15f), UnityEngine.Random.Range(position.y - 10f, Values.Instance.AreaSize - 5));
		}
		if (position.y > (float)(Values.Instance.AreaSize / 2))
		{
			return new Vector2(UnityEngine.Random.Range(position.x + 15f, Values.Instance.AreaSize - 5), UnityEngine.Random.Range(5f, position.y - 10f));
		}
		return new Vector2(UnityEngine.Random.Range(position.x + 15f, Values.Instance.AreaSize - 5), UnityEngine.Random.Range(position.y - 10f, Values.Instance.AreaSize - 5));
	}

	private IEnumerator RevivePlayerRoutine()
	{
		while (true)
		{
			yield return new WaitUntil(() => deadCharacters.Count > 0);
			yield return new WaitForSeconds(1f);
			Character c = deadCharacters.Dequeue();
			InitializePlayer(c, c.Index);
		}
	}

	public void StartGame(bool isFaster = false)
	{
		BGMManager.Instance.PlayBGM(Const.BGM2);
		UIScreenController.instance.OpenGame();
		MyAdManager.Instance.MyShowStartBox(() =>
		{
			InitializePlayer(playerCharacter, playerCharacterIndex, (!isFaster) ? 100 : 5000);
			startTime = Time.time;
			AnalyticManager.SendEvent(string.Format("Selected_Skin_" + FidgetStore.fidgetTypes[SelectedSkinIndex].name));
			if (GameManager.OnGameStart != null)
			{
				GameManager.OnGameStart();
			}
		});

	}

	public void EndGame()
	{
		AdManager.Instance.ShowNative();
		if (GameManager.OnGameEnd != null)
		{
			GameManager.OnGameEnd();
		}
		LastGameLenght = Time.time - startTime;
		ScoreManager.LastSurviveTime = LastGameLenght;
		ScoreManager.TotalKillCount += ScoreManager.LastKill;
		SendGameAnalytics();
		SkinCollection.Instance.CheckItems();
		if (SkinCollection.Instance.IndexList.Count > 0)
		{
			UIScreenController.instance.OpenCongrats();
		}
		else if (!Instance.screenshotTaken)
		{
			UIScreenController.instance.OpenMenu();
		}
		else
		{
			UIScreenController.instance.OpenScreenshot();
		}
	}

	private void SendGameAnalytics()
	{
		AnalyticManager.SendEvent(AnalyticManager.PlayTime, (int)ScoreManager.LastSurviveTime);
		AnalyticManager.SendEvent(AnalyticManager.LastSurvivalTime, (int)ScoreManager.LastSurviveTime);
		AnalyticManager.SendEvent(AnalyticManager.LastKillCount, ScoreManager.LastKill);
		AnalyticManager.SendEvent(AnalyticManager.LastMass, ScoreManager.LastMass);
	}

	private void OnApplicationPause(bool paused)
	{
		if (paused && playerCharacter.IsAlive)
		{
			playerCharacter.Mass = 0;
			playerCharacter.Finalize();
		}
	}

	public void AddDeadCharacter(Character dead)
	{
		deadCharacters.Enqueue(dead);
	}

	public void CharacterCollision(Character hitter, Character hitted)
	{
		int num = 0;
		int num2 = 0;
		int num3 = 0;
		int num4 = 0;
		int num5 = 0;
		float num6 = 0f;
		num3 = hitter.Mass;
		num4 = hitted.Mass;
		if (num3 >= num4)
		{
			num = Mathf.CeilToInt((float)num3 * Values.Instance.BigDamageRatio);
			num2 = Mathf.CeilToInt((float)num4 * Values.Instance.LightDamageRatio);
		}
		else
		{
			num = Mathf.CeilToInt((float)num3 * Values.Instance.LightDamageRatio);
			num2 = Mathf.CeilToInt((float)num4 * Values.Instance.BigDamageRatio);
		}
		hitted.Mass -= num;
		hitter.Mass -= num2;
		if (hitter.Mass <= 0)
		{
			hitter.Finalize();
			hitted.KillCount++;
			num2 = num3;
			if (hitter.Index == playerCharacterIndex)
			{
				FollowingCamera.instance.PlayCollisionAnim();
			}
		}
		else if (hitted.Mass <= 0)
		{
			hitted.Finalize();
			hitter.KillCount++;
			num = num4;
			if (hitted.Index == playerCharacterIndex)
			{
				SFXManager.Instance.PlaySFX(Const.HitSFX);
				FollowingCamera.instance.PlayCollisionAnim();
			}
		}
		num5 = Mathf.CeilToInt((float)(num + num2) * 0.8f);
		num6 = Angle(hitted.Position, hitter.Position);
		hitter.GiveForce(new Vector2(Mathf.Cos((float)Math.PI / 180f * num6), Mathf.Sin((float)Math.PI / 180f * num6)), Values.Instance.HitForce);
		num6 = Angle(hitter.Position, hitted.Position);
		hitted.GiveForce(new Vector2(Mathf.Cos((float)Math.PI / 180f * num6), Mathf.Sin((float)Math.PI / 180f * num6)), Values.Instance.HitForce);
		Vector3 start = (hitted.Position + hitter.Position) / 2f;
		int[] array = GenerateMassCountByLevel(num5);
		for (int i = 0; i < array.Length; i++)
		{
			for (int j = 0; j < array[i]; j++)
			{
				Collectible collectible = CollectiblePool.Instance.GetCollectible();
				if (collectible != null)
				{
					collectible.InitializeWithMove(i + 1, (int)Mathf.Pow(2f, i), Instance.RandomColor(), start, UnityEngine.Random.insideUnitCircle * UnityEngine.Random.Range(4f, 9f) * 75f);
				}
			}
		}
	}

	public void CharacterCollision(Character hitter, ContactPoint2D contact)
	{
		int num = Mathf.CeilToInt((float)hitter.Mass * 0.2f);
		hitter.Mass -= num;
		if (hitter.Mass <= 0)
		{
			hitter.Finalize();
		}
		else
		{
			hitter.GiveForce(2f * Vector2.Dot(-hitter.MoveDirection, contact.normal) * contact.normal + hitter.MoveDirection, Values.Instance.HitForce);
		}
		int mass = Mathf.CeilToInt((float)num * 0.8f);
		float num2 = Angle(-contact.normal, Vector2.zero) - 45f;
		Vector3 start = contact.point + contact.normal / 5f;
		int[] array = GenerateMassCountByLevel(mass);
		for (int i = 0; i < array.Length; i++)
		{
			for (int j = 0; j < array[i]; j++)
			{
				Collectible collectible = CollectiblePool.Instance.GetCollectible();
				if (collectible != null)
				{
					float angle = num2 + (float)UnityEngine.Random.Range(0, 90);
					collectible.InitializeWithMove(i + 1, (int)Mathf.Pow(2f, i), Instance.RandomColor(), start, Quaternion.AngleAxis(angle, Vector3.forward) * Vector3.right * UnityEngine.Random.Range(1f, 4f) * 75f);
				}
			}
		}
	}

	public void CharacterCollisionWithBouble(Bubble bubble, Character hitter, ContactPoint2D contact)
	{
		hitter.GiveForce(-hitter.MoveDirection, Values.Instance.HitForce / 2f);
		float num = Angle(contact.normal, Vector2.zero) - 45f;
		Vector3 start = contact.point + bubble.transform.localScale.x * bubble.CCollider.radius * -2.25f * contact.normal;
		int num2 = Mathf.CeilToInt((float)hitter.Mass * Values.Instance.BigDamageRatio);
		num2 = ((num2 < bubble.Mass) ? num2 : bubble.Mass);
		int[] array = GenerateMassCountByLevel(num2);
		for (int i = 0; i < array.Length; i++)
		{
			for (int j = 0; j < array[i]; j++)
			{
				Collectible collectible = CollectiblePool.Instance.GetCollectible();
				if (collectible != null)
				{
					float angle = num + (float)UnityEngine.Random.Range(0, 90);
					collectible.InitializeWithMove(i + 1, (int)Mathf.Pow(2f, i), Instance.RandomColor(), start, Quaternion.AngleAxis(angle, Vector3.forward) * Vector3.right * UnityEngine.Random.Range(150, 250));
				}
			}
		}
		bubble.Mass -= num2;
		if (bubble.Mass <= 0)
		{
			bubble.Finalize();
		}
	}

	public static int[] GenerateMassCountByLevel(int mass)
	{
		int num = 8;
		int[] array = new int[14];
		int num2 = 0;
		if (mass > 500)
		{
			num2 = 3;
		}
		else if (mass > 1000)
		{
			num2 = 5;
		}
		while (mass > 0)
		{
			for (int i = num2; i < array.Length; i++)
			{
				int num3 = (int)Mathf.Pow(2f, i);
				if (mass / num3 > num)
				{
					array[i] += num;
					mass -= num3 * num;
				}
				else
				{
					array[i] += mass / num3;
					mass %= num3;
				}
			}
			num2 = 0;
		}
		return array;
	}

	public static Vector2 GetRandomDirection()
	{
		float num = (float)UnityEngine.Random.Range(-100, 100) / 100f;
		float y = (1f - Mathf.Abs(num)) * (float)((UnityEngine.Random.Range(0, 2) > 0) ? 1 : (-1));
		return new Vector2(num, y);
	}

	public static Vector2 GetRandomPosition(float distanceFromEdge)
	{
		return new Vector2(UnityEngine.Random.Range(distanceFromEdge, (float)Values.Instance.AreaSize - distanceFromEdge), UnityEngine.Random.Range(distanceFromEdge, (float)Values.Instance.AreaSize - distanceFromEdge));
	}

	public static float Angle(Vector2 vec1, Vector2 vec2)
	{
		float num = Mathf.Atan2(vec1.y - vec2.y, vec1.x - vec2.x) * 57.29578f - 180f;
		if (num < 0f)
		{
			num += 360f;
		}
		return num;
	}

	public Color RandomColor()
	{
		return hueTex.GetPixel(UnityEngine.Random.Range(0, 8), 1);
	}
}
